package com.javalearn;

import java.util.concurrent.atomic.AtomicInteger;

public class SynchronizeWait {
	static volatile boolean flag = true; //如果已经很明确flag会在多个线程的同步(synchronize)操作被修改，可以不加volatile，synchronize会保证共享变量的可见性
	static Object lock = new Object();
	static AtomicInteger count = new AtomicInteger(1);
	static class Wait implements Runnable{
		public void run() {
			synchronized(lock) {
				while(flag) {//为什么不用if 1.flag初始值为true 业务逻辑为为假是跳出循环，如果用if，其他线程在不修改flag为false的情况下notify,那么这个业务逻辑会被打破 
					try {
						System.out.println("waiting "+count.getAndIncrement() + " time");
						lock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println("wait exit.....");
				}
			}
		}
	}

	static class Notify implements Runnable{
		public void run() {
			synchronized(lock) {
				System.out.println("notify exit111...");
				lock.notify();//测试1 先屏蔽掉此行代码，Notify的run执行完后，Wait的run是否会执行，结果不会，说明Monitor.exit不能唤醒Wait中的run
				//因为lock.wait后，waitThread线程进入的是WaitSet集合，该集合的线程只能由notify()/notifyAll()唤醒
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println("notify exit222...");
		}
	}

	static class Normal implements Runnable{
		public void run() {
			synchronized(lock) {
				System.out.println("Normal...");
				flag = false;
				lock.notify();
			}
		}
	}

	public static void main(String[] args) {
		Thread waitThread = new Thread(new Wait());
		Thread notifyThread = new Thread(new Notify());
		Thread normalThread = new Thread(new Normal());
		waitThread.start();
		notifyThread.start();
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		normalThread.start();
	}
}
